﻿using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;

namespace SigowayCommonLib
{
    public static class SingleInstance
    {
        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        private const int WS_SHOWNORMAL = 1;

        public static Process GetRunningInstance()
        {
            // 获取当前进程
            Process currentProcess = Process.GetCurrentProcess();
            // 获取当前运行程序完全限定名 
            string currentFileName = currentProcess.MainModule.FileName;
            // 获取进程名为ProcessName的Process数组。 
            Process[] processes = Process.GetProcessesByName(currentProcess.ProcessName);
            // 遍历有相同进程名称正在运行的进程 
            foreach (Process process in processes)
            {
                if (process.MainModule.FileName != currentFileName)
                {
                    continue;
                }

                // 根据进程ID排除当前进程
                if (process.Id != currentProcess.Id)
                {
                    // 返回已运行的进程实例 
                    return process;
                }

            }
            return null;
        }

        public static bool HandleRunningInstance(Process instance)
        {
            // 确保窗口没有被最小化或最大化 
            ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
            // 设置为foreground window 
            return SetForegroundWindow(instance.MainWindowHandle);
        }

        public static bool HandleRunningInstance()
        {
            // 互斥方法1
            Process p = GetRunningInstance();
            // 已经有应用程序副本执行
            if (p != null)
            {
                HandleRunningInstance(p);
                return true;
            }

            return false;
        }

        /// <summary>
        ///     互斥体
        /// </summary>
        /// <returns>true: 存在当前进程 False：不存在当前进程</returns>
        public static bool HandleRunningInstanceByMutex(string name)
        {
            // 互斥方法2
            bool bCreateNew = false;
            // 互斥实体
            Mutex mutex = new Mutex(false, string.IsNullOrEmpty(name) ? "Sigoway" : name, out bCreateNew);

            if (!bCreateNew)
            {
                HandleRunningInstance();
                return true;
            }

            return false;
        }
    }
}